import { Component, OnInit, ViewChild, TemplateRef } from '@angular/core'
import { Router, ActivatedRoute } from '@angular/router'
import { NzMessageService } from 'ng-zorro-antd'
import { STColumn } from '@delon/abc'
import { ACLService } from '@delon/acl'
import { SettingsService } from '@delon/theme'

import { I18NService } from '@core'
import { ListBaseClass } from '@shared/classes/ListBaseClass'
import { Role, IRoleQueryParams, roleLevelMap } from '@shared/interfaces/role'
import { RoleService } from '../role.service'
import { ISearchSchema } from '@shared/interfaces/search'
import { ESearchType } from '@shared/enums'
import { ModalService } from '@shared/services/modal.service'
import { StatusTextMap } from '@shared/interfaces/common'
import { AAMSFilterInit } from '@shared/interfaces/aams'

@Component({
  selector: 'app-role-list',
  templateUrl: './list.component.html',
  styleUrls: ['../../../shared/styles/table.less'],
})
export class RoleListComponent extends ListBaseClass<Role, IRoleQueryParams> implements OnInit, AAMSFilterInit {
  @ViewChild('tplAcquirer') tplAcquirer: TemplateRef<void>
  roleLevelMap = roleLevelMap

  searchSchema: ISearchSchema[] = []

  StatusTextMap = StatusTextMap

  columns: STColumn[] = []

  roleStatusOptions = [
    { label: this.trans(StatusTextMap['normal']), value: 'normal' },
    { label: this.trans(StatusTextMap['freeze']), value: 'freeze' },
  ]

  constructor(
    public msg: NzMessageService,
    public i18n: I18NService,
    public router: Router,
    public route: ActivatedRoute,
    public settings: SettingsService,
    public modalService: ModalService,
    public aclService: ACLService,
    private roleService: RoleService,
  ) {
    super(msg, i18n, route, router, settings)
  }

  ngOnInit() {
    this.initColumns()
    this.parseParams().subscribe(() => {
      this.queryTableDataWithParams()
    })
    this.initialAAMSFilter()
    this.setupUserRoleSelectionPermit()
    this.searchSchema = this.generateSearchSchema()
  }

  initialAAMSFilter() {
    this.initAcquirer()
  }

  queryTableDataWithParams(): void {
    this.loading = true
    this.roleService.getList(this.params).subscribe(this.renderList.bind(this), this.getListError.bind(this))
  }

  goNew(): void {
    this.router.navigate(['../new'], { relativeTo: this.route })
  }

  delete(role: Role): void {
    const { roleId } = role
    this.modalService.delete(this.trans('GENERAL.NOTIFICATION.DELETE_CONFIRM')).subscribe(isOk => {
      if (!isOk) {
        return
      }
      this.roleService.deleteRole(roleId + '').subscribe(() => this.deleteSuccess(), err => this.deleteFail())
    })
  }

  freezeDialog(role: Role): void {
    const { roleName, roleId } = role
    const msg = this.trans('GENERAL.NOTIFICATION.ROLE_FREEZE_CONFIRM', {roleName})
    this.modalService.freezeAndUnFreeze(msg).subscribe(operate => {
      if (operate) {
        this.freeze(roleId)
      }
    })
  }

  unfreezeDialog(role: Role): void {
    const { roleName, roleId } = role
    const msg = this.trans('GENERAL.NOTIFICATION.ROLE_UNFREEZE_CONFIRM', {roleName})
    this.modalService.freezeAndUnFreeze(msg).subscribe(operate => {
      if (operate) {
        this.unfreeze(roleId)
      }
    })
  }

  freeze(roleId: number): void {
    this.roleService.freeze(roleId).subscribe(
      res => {
        this.st.reload()
        this.msg.success(this.trans('GENERAL.NOTIFICATION.FREEZE_SUCCESS'))
      },
      err => {
        this.msg.error(this.trans('GENERAL.NOTIFICATION.FREEZE_FAIL'))
      },
    )
  }

  unfreeze(roleId: number): void {
    this.roleService.unfreeze(roleId).subscribe(
      res => {
        this.st.reload()
        this.msg.success(this.trans('GENERAL.NOTIFICATION.UNFREEZE_SUCCESS'))
      },
      err => {
        this.msg.error(this.trans('GENERAL.NOTIFICATION.UNFREEZE_FAIL'))
      },
    )
  }

  copy(role: Role): void {
    this.router.navigate([`../copy/from/${role.roleId}`], { relativeTo: this.route })
  }

  getRoleType(roleType: string): string {
    try {
      return this.trans(roleLevelMap[roleType])
    } catch (e) {
      return this.trans('GENERAL.INFO.NONE')
    }
  }

  getRoleStatus(status: string): string {
    try {
      return this.trans(StatusTextMap[status])
    } catch (e) {
      return this.trans('GENERAL.INFO.NONE')
    }
  }

  private deleteSuccess(): void {
    this.msg.success(this.trans('GENERAL.NOTIFICATION.DELETE_SUCCESS'))
    this.queryTableDataWithParams()
  }

  private deleteFail(): void {
    this.msg.error(this.trans('GENERAL.NOTIFICATION.DELETE_FAIL'))
  }

  private initColumns() {
    const canLock = this.aclService.canAbility('api.put.camel.role.one.freeze')
    const canUnlock = this.aclService.canAbility('api.put.camel.role.one.unfreeze')
    const canDelete = this.aclService.canAbility('api.delete.camel.role.one')
    const canCreate = this.aclService.canAbility('api.post.camel.role.one')
    this.columns = [
      {
        type: 'link',
        title: '角色编号',
        i18n: 'ROLE.ROLE_ID',
        index: 'roleId',
        width: '150px',
        fixed: 'left',
        className: 'text-center',
        click: this.goDetail.bind(this),
      },
      {
        title: '角色名称',
        i18n: 'ROLE.ROLE_NAME',
        index: 'roleName',
        width: '150px',
        className: 'text-left',
      },
      {
        title: '归属机构',
        i18n: 'ROLE.OWNER_INSTITUTION',
        index: 'insCodes',
        width: '200px',
        className: 'text-center',
      },
      {
        title: '角色层级',
        i18n: 'ROLE.ROLE_LEVEL',
        width: '100px',
        className: 'text-center',
        render: 'roleType',
      },
      {
        title: '角色描述',
        i18n: 'ROLE.ROLE_DESC',
        index: 'roleDesc',
        width: '300px',
        className: 'text-left',
      },
      {
        title: '状态',
        i18n: 'GENERAL.INFO.STATUS',
        index: 'status',
        width: '100px',
        className: 'text-center',
        render: 'status',
      },
      {
        title: '操作',
        i18n: 'GENERAL.INFO.OPERATION',
        width: '150px',
        fixed: 'right',
        className: 'text-center p-xs',
        iif: () => canLock || canUnlock || canDelete || canCreate,
        buttons: [
          {
            text: '',
            icon: {
              iconfont: 'icon-delete-circle',
              type: 'iconfont',
            },
            click: this.delete.bind(this),
            iif: () => canDelete,
          },
          {
            icon: {
              iconfont: 'icon-lock-twotone',
              type: 'iconfont',
            },
            click: this.freezeDialog.bind(this),
            iif: record => canLock && record.status === 'normal',
          },
          {
            icon: {
              iconfont: 'icon-unlock-circle',
              type: 'iconfont',
            },
            click: this.unfreezeDialog.bind(this),
            iif: record => canUnlock && record.status === 'freeze',
          },
          {
            icon: {
              iconfont: 'icon-copy-circle-twotone',
              type: 'iconfont',
            },
            click: record => this.copy(record as Role),
            iif: () => canCreate,
          },
        ],
      },
    ]
  }

  private generateSearchSchema(): ISearchSchema[] {
    return [
      {
        label: 'ROLE.ROLE_ID',
        labelI18n: 'ROLE.ROLE_ID',
        index: 'roleId',
        type: ESearchType.input,
      },
      {
        label: 'ROLE.ROLE_NAME',
        labelI18n: 'ROLE.ROLE_NAME',
        index: 'roleName',
        type: ESearchType.input,
      },
      {
        label: 'GENERAL.INFO.STATUS',
        labelI18n: 'GENERAL.INFO.STATUS',
        index: 'status',
        type: ESearchType.selection,
        options: this.roleStatusOptions,
      },
      {
        label: 'ROLE.OWNER_INSTITUTION',
        labelI18n: 'ROLE.OWNER_INSTITUTION',
        index: 'insCode',
        component: this.tplAcquirer,
        customFunc: () => this.selectedAcquirer && this.selectedAcquirer.code,
      },
      {
        label : 'ROLE.ROLE_LEVEL',
        labelI18n: 'ROLE.ROLE_LEVEL',
        index: 'roleType',
        type: ESearchType.selection,
        options: this.userTypes,
      },
    ]
  }

  private goDetail(record: Role): void {
    const { roleId } = record
    this.router.navigate([`../${roleId}`], { relativeTo: this.route })
  }
}
